﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace Skybrud.Social.Twitter {

    public class TwitterOAuth {

        public string ConsumerKey;
        public string ConsumerSecret;
        public string Nonce;
        public string Timestamp;
        public string Token;
        public string TokenSecret;
        public string Version;

        public string GenerateHeaderString(string signature) {

            string oauthHeaders = "OAuth ";
            oauthHeaders += "oauth_consumer_key=\"" + Uri.EscapeDataString(ConsumerKey) + "\", ";
            oauthHeaders += "oauth_nonce=\"" + Uri.EscapeDataString(Nonce) + "\", ";
            oauthHeaders += "oauth_signature=\"" + Uri.EscapeDataString(signature) + "\", ";
            oauthHeaders += "oauth_signature_method=\"HMAC-SHA1\", ";
            oauthHeaders += "oauth_timestamp=\"" + Timestamp + "\", ";
            oauthHeaders += "oauth_token=\"" + Uri.EscapeDataString(Token) + "\", ";
            oauthHeaders += "oauth_version=\"" + Version + "\"";

            return oauthHeaders;

        }

        public string GenerateParameterString(NameValueCollection queryString) {
            return GenerateParameterString(queryString, null);
        }

        public string GenerateParameterString(NameValueCollection queryString, NameValueCollection body) {

            SortedDictionary<string, string> sorted = new SortedDictionary<string, string>();

            if (queryString != null) {
                foreach (string key in queryString) {
                    sorted.Add(Uri.EscapeDataString(key), Uri.EscapeDataString(queryString[key]));
                }
            }
            
            if (body != null) {
                foreach (string key in body) {
                    sorted.Add(Uri.EscapeDataString(key), Uri.EscapeDataString(body[key]));
                }
            }

            // Add OAuth values
            sorted.Add("oauth_consumer_key", ConsumerKey);
            sorted.Add("oauth_nonce", Nonce);
            sorted.Add("oauth_signature_method", "HMAC-SHA1");
            sorted.Add("oauth_timestamp", Timestamp);
            sorted.Add("oauth_token", Token);
            sorted.Add("oauth_version", Version);

            // Merge all parameters
            return sorted.Aggregate("", (current, pair) => current + ("&" + pair.Key + "=" + pair.Value)).Substring(1);

        }

        public string GenerateSignatureKey() {
            return Uri.EscapeDataString(ConsumerSecret) + "&" + Uri.EscapeDataString(TokenSecret);
        }

        public string GenerateSignatureValue(string method, string url, NameValueCollection queryString, NameValueCollection body) {
            return String.Format(
                "{0}&{1}&{2}",
                method,
                Uri.EscapeDataString(url.Split('#')[0].Split('?')[0]),
                Uri.EscapeDataString(GenerateParameterString(queryString, body))
            );
        }

        public string GenerateSignature(string method, string url, NameValueCollection queryString, NameValueCollection body) {
            HMACSHA1 hasher = new HMACSHA1(new ASCIIEncoding().GetBytes(GenerateSignatureKey()));
            return Convert.ToBase64String(hasher.ComputeHash(new ASCIIEncoding().GetBytes(GenerateSignatureValue(method, url, queryString, body))));
        }
    
    }

}
